package de.szut.util;

/**
 * Utility class for checking if a value is in a certain range
 * @author Marc Huisinga
 *
 */
public final class RangeChecker implements Immutable {
	
	private final double min;
	private final double max;
	
	/**
	 * Constructor
	 * @param min - lower bound for range comparison
	 * @param max - upper bound for range comparison
	 */
	public RangeChecker(double min, double max) {
		this.min = min;
		this.max = max;
	}
	
	/**
	 * Checks if the value is in the specified range inclusively (returns true if value equals min or max) 
	 * @param value - value to check
	 * @return result
	 */
	public boolean isInRangeInclusive(double value) {
		return value>=min && value<=max;
	}
	
	/**
	 * Checks if the value is in the specified range exclusively (returns false if value equals min or max) 
	 * @param value - value to check
	 * @return result
	 */
	public boolean isInRangeExclusive(double value) {
		return value>min && value<max;
	}
	
	/**
	 * Checks if the value is in the specified range with min being inclusive and max being exclusive 
	 * (returns true if value equals min but equals false if value equals max) 
	 * @param value - value to check
	 * @return result
	 */
	public boolean isInRange(double value) {
		return value>=min && value<max;
	}

	/**
	 * Gets the lower bound for range comparison
	 * @return lower bound
	 */
	public double getMin() {
		return min;
	}

	/**
	 * Gets the upper bound for range comparison
	 * @return upper bound
	 */
	public double getMax() {
		return max;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(max);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(min);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof RangeChecker)) {
			return false;
		}
		RangeChecker other = (RangeChecker) obj;
		if (Double.doubleToLongBits(max) != Double.doubleToLongBits(other.max)) {
			return false;
		}
		if (Double.doubleToLongBits(min) != Double.doubleToLongBits(other.min)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("RangeChecker [min=");
		builder.append(min);
		builder.append(", max=");
		builder.append(max);
		builder.append("]");
		return builder.toString();
	}
}
